Skip to main content

JavaScript Execution Context & Lexical Environment - Complete Guide

Interview-Ready Reference | FAANG-Level Depth


Table of Contentsโ€‹

  1. Execution Context
  2. Lexical Environment
  3. The Big Picture: How They Work Together
  4. Closures Explained
  5. Interview Traps & Edge Cases
  6. Quick Reference Tables
  7. One-Liners to Memorize

1. Execution Contextโ€‹

Core Conceptโ€‹

Execution Context = the environment in which JavaScript code is evaluated and executed

Think of it as a runtime box that stores:

  • Variables
  • Functions
  • Scope chain
  • this value

Key Rule: JavaScript always runs inside an execution context. No context โ†’ no execution.


Types of Execution Contextsโ€‹

JavaScript has 3 main types:

  1. Global Execution Context (GEC)
  2. Function Execution Context (FEC)
  3. Eval Execution Context (rare, ignore in interviews)

We'll focus on GEC + FEC.


Global Execution Context (GEC)โ€‹

When is it created?

  • Immediately when JS file starts executing
  • Only one GEC per program

What does GEC contain?

  1. Global Object

    • Browser โ†’ window
    • Node.js โ†’ global
    • Global variables & functions attach here
  2. this

    • In browser โ†’ this === window
    • In strict mode โ†’ undefined
  3. Memory & Code Phases

๐Ÿ” GEC is created in two phasesโ€‹

Phase 1: Memory Creation (Hoisting Phase)

var a = 10;
let b = 20;
function foo() {
console.log("hello");
}

Memory Phase:

  • a โ†’ undefined
  • b โ†’ <uninitialized> (Temporal Dead Zone)
  • foo โ†’ function reference

Phase 2: Code Execution Phase

  • Values assigned
  • Code executed line by line
  • a โ†’ 10
  • b โ†’ 20

Function Execution Context (FEC)โ€‹

When is it created?

  • Every time a function is invoked
  • Each call gets a new execution context

What does a Function Execution Context contain?

  1. Arguments object
  2. Local variables
  3. Inner function declarations
  4. this value
  5. Scope chain (lexical environment)

Exampleโ€‹

function add(x, y) {
let sum = x + y;
return sum;
}
add(2, 3);

FEC Creation Phases

Phase 1: Memory Creation

  • x โ†’ 2
  • y โ†’ 3
  • sum โ†’ <uninitialized>

Phase 2: Execution

  • sum = 5
  • return 5

Once return executes โ†’ FEC is destroyed.


Call Stack (Execution Context Stack)โ€‹

JavaScript manages contexts using a Call Stack (LIFO - Last In First Out).

Exampleโ€‹

function first() {
second();
}
function second() {
console.log("Hello");
}
first();

Stack Flow:

| second() |
| first() |
| Global |
  • second() finishes โ†’ popped
  • first() finishes โ†’ popped
  • Global remains

Visual Mental Model (Interview Gold)โ€‹

Call Stack:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ FEC: second() โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ FEC: first() โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ GEC โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Each function call:

  1. Push context
  2. Execute
  3. Pop context

Global vs Function Execution Context (Comparison)โ€‹

FeatureGlobal ECFunction EC
CreatedOn program startOn function call
CountOnly oneMultiple
VariablesGlobal variablesLocal variables
thiswindow (browser)Depends on call
LifetimeTill program endsTill function returns

2. Lexical Environmentโ€‹

Core Conceptโ€‹

Lexical Environment = where variables are physically written in the code

Not when code runs โ€” but where it is defined.

It decides:

  • Scope
  • Variable lookup
  • Closure behavior

"Lexical" = based on code structure, not runtime flow.


Formal Definition (Interview-safe)โ€‹

A Lexical Environment is a data structure that contains:

  1. Environment Record โ€“ stores variables & functions
  2. Outer Reference โ€“ link to the parent lexical environment
Lexical Environment
โ”œโ”€โ”€ Environment Record
โ””โ”€โ”€ Outer (reference to parent)

Lexical Scope (Core Rule)โ€‹

๐Ÿ‘‰ JavaScript uses Lexical (Static) Scoping

This means:

  • Scope is determined at write time
  • Not at call time

Exampleโ€‹

const a = 10;

function outer() {
const b = 20;

function inner() {
console.log(a, b);
}

inner();
}
outer();

Scope Chain:

  • inner โ†’ outer โ†’ global
  • a found in global
  • b found in outer

โœ”๏ธ This chain is decided before execution starts


Block Scope (let / const)โ€‹

Each {} creates a block lexical environment.

if (true) {
let x = 10;
const y = 20;
}
console.log(x); // โŒ ReferenceError

Block Lexical Env:

โ”œโ”€โ”€ x
โ”œโ”€โ”€ y
โ””โ”€โ”€ outer โ†’ global

โŒ var ignores block scope.


Scope Chain (Variable Resolution)โ€‹

When JS looks up a variable:

  1. Current lexical environment
  2. Parent lexical environment
  3. Continue until global
  4. If not found โ†’ ReferenceError

Exampleโ€‹

let a = 1;

function foo() {
let b = 2;

function bar() {
let c = 3;
console.log(a, b, c);
}
bar();
}

Lookup order in bar():

  • c โ†’ bar
  • b โ†’ foo
  • a โ†’ global

3. The Big Picture: How They Work Togetherโ€‹

Execution Context vs Lexical Environmentโ€‹

Execution ContextLexical Environment
Created at runtimeDefined by code structure
Manages executionManages scope
Pushed to call stackLinked via outer references
Destroyed after executionMay survive (closures)

๐Ÿ‘‰ Execution context contains a reference to its lexical environment


Complete Mental Modelโ€‹

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Execution Context โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ Lexical Environment โ”‚ โ”‚
โ”‚ โ”‚ โ”œโ”€โ”€ Environment Record โ”‚ โ”‚
โ”‚ โ”‚ โ””โ”€โ”€ Outer Reference โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ”œโ”€โ”€ this binding โ”‚
โ”‚ โ””โ”€โ”€ Variable Environment โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

4. Closures Explainedโ€‹

Definition: Closure = function + its lexical environment

function counter() {
let count = 0;
return () => {
count++;
return count;
};
}

const inc = counter();
inc(); // 1
inc(); // 2

Why does count survive?

Because:

  • Execution context of counter() is destroyed
  • Lexical environment is retained
  • inc holds reference to it

5. Interview Traps & Edge Casesโ€‹

โš ๏ธ Trap 1: Lexical โ‰  Dynamicโ€‹

function foo() {
console.log(x);
}

function bar() {
let x = 10;
foo();
}

let x = 5;
bar(); // 5 โŒ Not 10

โœ”๏ธ Lexical scope, not call-site scope


โš ๏ธ Trap 2: var vs let in loopsโ€‹

for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
// ๐Ÿ‘‰ Single lexical environment โ†’ 3 3 3
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
// ๐Ÿ‘‰ New lexical environment per iteration โ†’ 0 1 2

โš ๏ธ Trap 3: Are let and const hoisted?โ€‹

โœ”๏ธ Yes โŒ But not initialized โ†’ Temporal Dead Zone

console.log(a); // โŒ ReferenceError: Cannot access 'a' before initialization
let a = 10;

โš ๏ธ Trap 4: Does arrow function have its own execution context?โ€‹

โœ”๏ธ Execution context exists โŒ No arguments object โŒ No own this


6. Quick Reference Tablesโ€‹

Hoisting Behaviorโ€‹

TypeHoisted?Initialized?TDZ?
varโœ”๏ธ Yesโœ”๏ธ undefinedโŒ No
letโœ”๏ธ YesโŒ Noโœ”๏ธ Yes
constโœ”๏ธ YesโŒ Noโœ”๏ธ Yes
functionโœ”๏ธ Yesโœ”๏ธ Full definitionโŒ No

Scope Typesโ€‹

Scope TypeCreated ByVariables
GlobalProgram startvar, let, const, function
FunctionFunction callLocal variables, parameters
Block{}let, const only

7. One-Liners to Memorizeโ€‹

Execution Contextโ€‹

Execution Context is the runtime environment where JavaScript code runs. The global execution context is created first, and every function invocation creates its own execution context, all managed via the call stack.

Lexical Environmentโ€‹

Lexical Environment defines where variables live based on code structure, and JavaScript resolves variables using a scope chain formed via outer lexical references. Closures work because functions retain access to their defining lexical environment.

The Connectionโ€‹

Every execution context has a reference to a lexical environment. Execution contexts manage runtime flow; lexical environments manage scope and variable access.


Common Microsoft/Google Follow-up Questionsโ€‹

  1. Difference between Scope chain vs Call stack?

    • Call stack = execution order (runtime)
    • Scope chain = variable lookup (code structure)
  2. How closures cause memory leaks?

    • Retained lexical environments aren't garbage collected
    • If large objects are in outer scope, they persist
  3. Lexical environment vs Context object?

    • Lexical env = scope structure
    • Context object = this value
  4. How this differs from lexical scope?

    • this is dynamic (call-site dependent)
    • Lexical scope is static (write-time dependent)

End of Guide | Bookmark this for interviews ๐Ÿš€